package com.bosssoft.trainee.nontax.controller;

import com.alibaba.fastjson.JSONObject;
import com.bosssoft.trainee.nontax.annotation.UserLoginToken;
import com.bosssoft.trainee.nontax.common.result.CodeMsg;
import com.bosssoft.trainee.nontax.common.result.Result;
import com.bosssoft.trainee.nontax.entity.dto.UserDto;
import com.bosssoft.trainee.nontax.entity.dto.ElementTableData;
import com.bosssoft.trainee.nontax.entity.vo.UserVo;
import com.bosssoft.trainee.nontax.service.AuthorizeService;
import com.bosssoft.trainee.nontax.service.UserService;
import com.bosssoft.trainee.nontax.service.jwt.TokenService;
import com.bosssoft.trainee.nontax.util.mapper.dtoVo.UserDtoVo;
import com.bosssoft.trainee.nontax.util.mapper.poDto.UserPoDto;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.LinkedList;
import java.util.List;

@Slf4j
@Controller
public class UserController {
    @Autowired
    UserService userService;

    @Autowired
    UserPoDto userPoDto;

    @Autowired
    UserDtoVo userDtoVo;

    @Autowired
    AuthorizeService authorizeService;

    @Autowired
    TokenService tokenService;

    // Hystrix data
    private final UserVo userVo = UserVo.builder()
            .userId(-1)
            .name("no use data")
            .description("please refresh later").build();

    @RequestMapping("/user/getAll")
    @ResponseBody
    @UserLoginToken
    @HystrixCommand(fallbackMethod = "getAllUserByElementTableDataTemplateHystrix")
    public Result<ElementTableData<UserVo>> getAllUserByElementTableDataTemplate() {
        List<UserVo> userVos = userService.queryByPage(UserDto.builder().build());
        return Result.success(new ElementTableData<>(userVos,userVos.size()));
    }

    public Result<ElementTableData<UserVo>> getAllUserByElementTableDataTemplateHystrix() {
        LinkedList<UserVo> users = new LinkedList<>();
        users.add(userVo);
        return Result.success(new ElementTableData<>(users,users.size()));
    }

    @ResponseBody
    @RequestMapping("/user/getUserById")
    @HystrixCommand(fallbackMethod = "getUserByIdHystrix")
    public Result<UserVo> getUserById(@RequestParam Integer id) {
        return Result.success(userService.queryById(id));
    }

    public Result<UserVo> getUserByIdHystrix(@RequestParam Integer id) {
        return Result.success(userVo);
    }

    @ResponseBody
    @RequestMapping("/user/getUserByToken")
    @HystrixCommand(fallbackMethod = "getUserByTokenHystrix")
    public Result<UserVo> getUserByToken(@RequestParam String token) {
        Integer userId = tokenService.getUserIdFromToken(token);
        UserVo userVo = userService.queryById(userId);
        return Result.success(userVo);
    }

    public Result<UserVo> getUserByTokenHystrix(@RequestParam String token) {
        return Result.success(userVo);
    }

    @RequestMapping("/user/getAllUser")
    @ResponseBody
    @UserLoginToken
    @HystrixCommand(fallbackMethod = "getAllUserHystrix")
    public Result<List<UserVo>> getAllUser() {
        List<UserVo> userVos = userService.queryByPage(UserDto.builder().build());
        return Result.success(userVos);
    }

    public Result<List<UserVo>> getAllUserHystrix() {
        List<UserVo> users = new LinkedList<>();
        return Result.success(users);
    }

    @RequestMapping("/user/getAllByRoleId")
    @ResponseBody
    @UserLoginToken
    @HystrixCommand(fallbackMethod = "getAllUserLimitedByRoleIdHystrix")
    public Result<ElementTableData<UserVo>> getAllUserLimitedByRoleId(@RequestParam Integer roleId) {
        List<UserVo> users = userService.queryAllByRoleId(roleId);
        return Result.success(new ElementTableData<>(users, users.size()));
    }

    public Result<ElementTableData<UserVo>> getAllUserLimitedByRoleIdHystrix(@RequestParam Integer roleId) {
        List<UserVo> users = new LinkedList<>();
        users.add(userVo);
        return Result.success(new ElementTableData<>(users, users.size()));
    }

    @RequestMapping("/user/addUser")
    @ResponseBody
    @UserLoginToken // {"QQ":[""],"role":[""],"sex":["男"],"birth":["2022-06-22T16:00:00.000Z"],"dept":[""],"idNumber":["5003832000121643
    @HystrixCommand(fallbackMethod = "addUserHystrix")
    public Result<UserVo> addUser(@RequestBody UserVo userVo) {
        log.info(userVo.toString());
        userVo = userService.insert(userDtoVo.vo2dto(userVo));
        return Result.success(userVo);
    }

    public Result<UserVo> addUserHystrix(@RequestBody UserVo userVo) {
        return Result.error(CodeMsg.HYSTRIX_METHOD);
    }

    @RequestMapping("/user/deleteUser")
    @ResponseBody
    @UserLoginToken
    @HystrixCommand(fallbackMethod = "deleteUserByUserIdHystrix")
    public Result<Object> deleteUserByUserId(@RequestParam Integer userId) {
        if (userId == null){
            return Result.error(CodeMsg.NOT_FIND_DATA);
        }
        return userService.deleteByIdSoft(userId) > 0 ?
                Result.success() :
                Result.error(CodeMsg.NOT_FIND_DATA);
    }

    public Result<Object> deleteUserByUserIdHystrix(@RequestParam Integer userId) {
        return Result.error(CodeMsg.HYSTRIX_METHOD);
    }

    @RequestMapping("/user/updateUser")
    @ResponseBody
    @UserLoginToken
    @HystrixCommand(fallbackMethod = "updateUserHystrix")
    public Result<UserVo> updateUser(@RequestBody UserVo userVo) {
        userService.update(userDtoVo.vo2dto(userVo));
        return Result.success();
    }

    public Result<UserVo> updateUserHystrix(@RequestBody UserVo userVo) {
        return Result.error(CodeMsg.HYSTRIX_METHOD);
    }
}
